/*
 * Copyright (c) 2002-2004
 * All rights reserved.
 */
package com.atlassian.jira.plugin.workflow.blockinglinks.condition;

import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.config.ConstantsManager;
import com.atlassian.jira.issue.comparator.StatusComparator;
import com.atlassian.jira.plugin.workflow.AbstractWorkflowPluginFactory;
import com.atlassian.jira.plugin.workflow.WorkflowPluginConditionFactory;
import com.opensymphony.workflow.loader.AbstractDescriptor;
import com.opensymphony.workflow.loader.ConditionDescriptor;
import org.ofbiz.core.util.UtilMisc;

import java.util.*;

public class WorkflowBlockingLinksConditionFactoryImpl extends AbstractWorkflowPluginFactory implements WorkflowPluginConditionFactory
{
    private final ConstantsManager constantsManager;

    public WorkflowBlockingLinksConditionFactoryImpl(ConstantsManager constantsManager)
    {
        this.constantsManager = constantsManager;
    }

    protected void getVelocityParamsForInput(Map velocityParams)
    {
        ConstantsManager constantsManager = ComponentManager.getInstance().getConstantsManager();
        Collection statuses = constantsManager.getStatuses();
        velocityParams.put("statuses", Collections.unmodifiableCollection(statuses));
    }

    protected void getVelocityParamsForEdit(Map velocityParams, AbstractDescriptor descriptor)
    {
        getVelocityParamsForInput(velocityParams);
        velocityParams.put("selectedStatuses", getSelectedStatusIds(descriptor));
    }

    protected void getVelocityParamsForView(Map velocityParams, AbstractDescriptor descriptor)
    {
        Collection selectedStatusIds = getSelectedStatusIds(descriptor);
        List selectedStatuses = new LinkedList();
        for (Iterator iterator = selectedStatusIds.iterator(); iterator.hasNext();)
        {
            String statusId = (String) iterator.next();
            selectedStatuses.add(constantsManager.getStatus(statusId));
        }

        // Sort the list of statuses so as they are displayed consistently
        Collections.sort(selectedStatuses, new StatusComparator());

        velocityParams.put("statuses", Collections.unmodifiableCollection(selectedStatuses));
    }

    public Map getDescriptorParams(Map conditionParams)
    {
        Collection statusIds = conditionParams.keySet();
        StringBuffer statIds = new StringBuffer();

        for (Iterator iterator = statusIds.iterator(); iterator.hasNext();)
        {
            statIds.append((String) iterator.next() + ",");
        }

        return UtilMisc.toMap("statuses", statIds.substring(0, statIds.length() - 1));
    }

    private Collection getSelectedStatusIds(AbstractDescriptor descriptor)
    {
        Collection selectedStatusIds = new LinkedList();
        if (!(descriptor instanceof ConditionDescriptor))
        {
            throw new IllegalArgumentException("Descriptor must be a ConditionDescriptor.");
        }

        ConditionDescriptor conditionDescriptor = (ConditionDescriptor) descriptor;

        String statuses = (String) conditionDescriptor.getArgs().get("statuses");
        StringTokenizer st = new StringTokenizer(statuses, ",");

        while (st.hasMoreTokens())
        {
            selectedStatusIds.add(st.nextToken());
        }

        return selectedStatusIds;
    }
}
